﻿using Devil;
using System;
using System.Collections;
using System.IO;
using System.Threading;

namespace CmdThreadTest
{
    internal class Program
    {
        public static string CalculateRelativePath(string root, string child)
        {
            var p1 = Path.GetFullPath(root);
            var p2 = Path.GetFullPath(child);
            if (p1 == p2 || p1.Length >= p2.Length)
                return null;
            if (p2.StartsWith(p1))
            {
                var last = p1[p1.Length-1];
                return p2.Substring(p1.Length + (last == '/' || last == '\\' ? 0 : 1));
            }
            else
                return null;
        }

        static void Main(string[] args)
        {
            Debug.Log(Path.GetFullPath("../../"));
            Debug.Log(CalculateRelativePath("../../", "temp\\file1/file2/file3"));

            Console.ForegroundColor = (ConsoleColor)((Thread.CurrentThread.ManagedThreadId % 15) + 1);
            ParallelDispatcher.InitApplicationData();
            ThreadFlag flag = new ThreadFlag();
            var job = ParallelUtils.Schedule(InitCmds, false);
            var job1 = ParallelUtils.Schedule(MainJob, "A", true, job);
            var job2 = ParallelUtils.Schedule(MainJob, "B", true, job);
            var job3 = ParallelUtils.Schedule(new Parallel("main"), 40, job);
            ParallelUtils.ScheduleLooper(ParallelDispatcher.MainUpdate, false);

            var combine = ParallelUtils.NewCombination("finish");
            combine.Combine(job);
            combine.Combine(job1);
            combine.Combine(job2);
            combine.Combine(job3);
            ParallelUtils.Schedule(Finish, flag, false, combine.GetHandler());
            while (!flag.IsAbort)
            {
                //ParallelDispatcher.MainUpdate(0.1f);
            }
            ParallelDispatcher.QuitApplication();
            Debug.Log("press only key to continue...");
            Console.ReadKey();
        }

        static IEnumerator MainJob(string info)
        {
            Debug.Log(info + " begin.");
            yield return new Parallel(info).Schedule(20);
            for(int i = 0; i < 3; i++)
            {
                yield return null;
                Debug.Log(string.Format("[Main]{0} @{1}", info, i+1));
            }
            yield return null;
            Debug.Log(string.Format( "[Main]{0} Complete.", info));
        }

        static void Finish(ThreadFlag flag)
        {
            Debug.Log("Finished.\n");
            flag.Abort();
        }

        static void InitCmds()
        {
            Debug.Log("Init Cmds");
        }

    }

    class Parallel : ICommandParallelFor<int>
    {
        string name;
        public Parallel(string name)
        {
            this.name = string.IsNullOrEmpty(name) ? "Def" : name;
        }

        public override string ToString()
        {
            return string.Format("parallel_{0}", name);
        }

        public void Execute(int data)
        {
            Debug.Log(ToString() +" @" + data);
        }

        public void OnParallelForComplete()
        {
            Debug.Log(ToString() + " Complete.");
        }
    }
}
